package away3d.animators  ;


import away3d.animators.data.VertexAnimationSequence ;
import away3d.animators.data.VertexAnimationState ;
import away3d.animators.utils.TimelineUtil ;
import away3d.arcane ;
import away3d.core.base.Geometry ;


/**
 * AnimationSequenceController provides a controller for single clip-based animation sequences (fe: md2, md5anim).
 */
class VertexAnimator extends AnimatorBase
{
    
    
    // TODO: seems _sequences is used as lookup so array wrong??
    private var _sequences      : Array<VertexAnimationSequence> ;
    private var _activeSequence : VertexAnimationSequence ;
    private var _absoluteTime   : Float ;
    private var _target         : VertexAnimationState ;
    private var _tlUtil         : TimelineUtil ;
    
    
    
    /**
     * Creates a new AnimationSequenceController object.
     */
    public function VertexAnimator(target : VertexAnimationState)
    {
        
        super() ;
        _sequences  = [] ;
        _target     = target ;
        _tlUtil     = new TimelineUtil() ;
        
    }
    
    
    /**
     * Plays a sequence with a given name. If the sequence is not found, it may not be loaded yet, and it will retry every frame.
     * @param sequenceName The name of the clip to be played.
     */
    public function play( sequenceName: String )
    {
        
        _activeSequence = _sequences[ Std.int( sequenceName ) ] ;
        
        if ( !_activeSequence )
        {
            throw new Error("Clip not found!") ;
        }
        reset() ;
        start() ;
        
    }
    
    private function reset()
    {
        
        _absoluteTime = 0 ;
        
    }
    
    /**
     * Adds a sequence to the controller.
     */
    public function addSequence( sequence: VertexAnimationSequence )
    {
        
        _sequences[ sequence.name ] = sequence ;
        
    }

    /**
     * @inheritDoc
     */
    override protected function updateAnimation( realDT: Float, scaledDT : Float )
    {
        var poses       = _target.poses ;
        var weights     = _target.weights ;
        _absoluteTime   += scaledDT ;
        
        _tlUtil.updateFrames( _absoluteTime, _activeSequence ) ;
        
        poses[ 0 ]      = _activeSequence._frames[ _tlUtil.frame0 ] ;
        poses[ 1 ]      = _activeSequence._frames[ _tlUtil.frame1 ] ;
        
        weights[ 0 ]    = 1 - (weights[uint(1)] = _tlUtil.blendWeight) ;
        
        _target.invalidateState() ;
    }
    
    
    /**
     * Retrieves a sequence with a given name.
     * @private
     */
    arcane function getSequence( sequenceName : String ) : VertexAnimationSequence
    {
        
        return _sequences[ sequenceName ] ;
        
    }
    
    
}
}